public class Code {
    private String plaintext, str, ciphertext;
    private char[] key56, keyL, keyR;

    protected static char[] keyInit = {
            57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
            10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
            63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
            14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
    };
    protected static char[] keyCompress = {
            14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
            23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
            41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
            44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
    };

    public void setPlaintext(String str){ this.plaintext = str; }
    public void setStr(String str){ this.str = str; }
    public void setCiphertext(String str){ this.ciphertext = str; }

    Code(String plaintext, String str){
        setPlaintext(plaintext);
        setStr(str);
        this.key56 = getFirstKey(str.toCharArray());
    }


    //返回56位密钥 - 选择置换
    private char[] getFirstKey(char[] key){
        char[] key56 = new char[56];
        int k=0;
        for(int i=0; i<56; i++){
            key56[i] = key[keyInit[i]-1];
        }
        for(int i=0; i<28; i++){
            this.keyL[i] = key56[i];
            this.keyR[i] = key56[i+28];
        }
        this.keyL = toLf(this.keyL,1);
        this.keyR = toLf(this.keyR,1);
        return key56;
    }
    //左移操作
    private char[] toLf(char[] key, int digit){
        char[] temp = new char[key.length];
        for(int i=0; i<key.length; i++){

            if(key.length-i > digit){
                temp[i] = key[i+1];
            }else {
                //wrong!!!
                temp[i] = key[key.length-i-1];
            }
        }
        return key;
    }
    //左移后合成为56位密钥
    private char[] toCombine(){
        char[] key56 = new char[56];
        for(int i=0; i<28; i++){
            key56[i] = keyL[i];
            key56[i+32] = keyR[i];
        }
        return key56;
    }

    //返回各轮密钥
    public char[] getKey(int round){
        if(round == 2 || round == 16 || round == 9){
            keyL = toLf(keyL,1);
            keyR = toLf(keyR,1);
        }else {
            keyL = toLf(keyL,2);
            keyR = toLf(keyR,2);
        }
        char[] key56 = toCombine();
        char[] key48 = new char[48];
        for(int i=0; i<48; i++){
            key48[i] = key56[keyCompress[i]-1];
        }
        return key48;
    }



}
